﻿using SlamDunk.CMS.BLL;
using SlamDunk.CMS.Model;
using SlamDunk.CMS.Model.FormatModel;
using SlamDunk.CMS.Model.ViewModel;
using SlamDunk.CMS.UI.Controllers;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.Mvc;
using SlamDunk.CMS.Model.DataModel;

namespace SlamDunk.CMS.UI.Areas.Admin.Controllers
{
    /// <summary>
    /// 菜单控制器
    /// </summary>
    public class MenuController : BaseController
    {
        #region 00.实例化业务层
        /// <summary>
        /// 实例化业务层
        /// </summary>
        private readonly MenusBll MenuBll = new MenusBll();
        #endregion

        #region 01.获取菜单列表
        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <returns>菜单列表</returns>
        public ActionResult GetMenuList()
        {
            return this.Content(OperateContext.Current.MainMenuTree);
        }
        #endregion

        #region 02.加载视图
        /// <summary>
        /// 加载视图
        /// </summary>
        /// <returns>视图</returns>
        public ActionResult Index()
        {
            return this.View();
        }
        #endregion

        #region 03.加载列表
        /// <summary>
        /// 加载菜单树
        /// </summary>
        /// <returns>菜单列表树形集合</returns>
        public ActionResult List()
        {
            //1.接收EasyUI请求
            int pId = this.Request["id"] == null ? 0 : int.Parse(this.Request["id"]);
            //2.查询所有菜单
            List<Menus> menuList = this.MenuBll.GetModelList().OrderBy(x => x.Sort).ToList();
            //3.将菜单集合转换为树形
            List<TreeModel> treeList = OperateContext.Current.MenuListToTree(menuList, 0);
            //4.返回Json字符串
            return this.Json(treeList, JsonRequestBehavior.AllowGet);
        }
        #endregion

        #region 04.添加——加载视图
        /// <summary>
        /// 添加——加载视图
        /// </summary>
        /// <param name="id">父Id</param>
        /// <returns>添加视图</returns>
        public ActionResult Add(int id)
        {
            //接收客户端提供的父Id，根据Id查询Name，并赋值给ViewBag
            this.ViewBag.PId = id;
            this.ViewBag.PName = this.MenuBll.GetModel(id).MenuName;
            return this.View();
        }
        #endregion

        #region 05.添加——提交添加
        /// <summary>
        /// 添加——提交添加
        /// </summary>
        /// <param name="model">视图模型</param>
        /// <returns>JsonModel</returns>
        public ActionResult AddConfirm(MenusView model)
        {
            //校验模型
            if (this.ModelState.IsValid)
            {
                //1.转换数据模型
                Menus dataModel = model.ToDataModel();
                //2.获取添加后的数据模型
                Menus newModel = this.MenuBll.Add(dataModel);
                //3.非空校验
                if (newModel != null)
                {
                    return OperateContext.Current.JsonModel(1, "添加成功！");
                }
                else
                {
                    return OperateContext.Current.JsonModel(0, "添加失败！");
                }
            }
            else    //模型校验失败
            {
                return OperateContext.Current.JsonModel(0, "您输入的数据有误，请重试！");
            }
        }
        #endregion

        #region 06.删除单个菜单节点及其所有下级菜单节点——递归
        /// <summary>
        /// 删除单行
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>JsonModel</returns>
        public ActionResult DeleteSingle(int id)
        {
            try             //涉及外键关联，须处理异常
            {
                //1.查询该实体对象是否存在
                Menus model = this.MenuBll.GetModel(id);
                if (model == null)
                {
                    return OperateContext.Current.JsonModel(0, "该菜单节点不存在！");
                }
                else //2.如果存在，则递归删除
                {
                    this.DeleteRecursion(id);     //删除给定菜单节点以及其所有下级菜单节点
                    return OperateContext.Current.JsonModel(1, "删除成功！");
                }
            }
            catch (Exception ex)
            {
                //写入日志

                //返回客户端错误消息
                return OperateContext.Current.JsonModel(0, ex.Message);
            }
        }
        /// <summary>
        /// 递归删除给定栏目及其所有下级栏目
        /// </summary>
        /// <param name="id">要删除的栏目Id</param>
        private void DeleteRecursion(int id)
        {
            //1.根据给定栏目Id获取所有下级栏目
            List<Menus> list = this.MenuBll.GetModelList(id);
            if (list.Count > 0)
            {
                //2.遍历下级栏目
                foreach (Menus menu in list)
                {
                    this.DeleteRecursion(menu.Id);      //递归
                }
            }
            //3.删除给定部栏目及下级栏目
            this.MenuBll.PhysicalDelete(id);
        }
        #endregion

        #region 07.删除选中的菜单节点
        /// <summary>
        /// 删除选中的菜单节点
        /// </summary>
        /// <param name="selectedIds">选中树节点的Id</param>
        /// <returns>JsonModel</returns>
        public ActionResult DeleteSelected(string selectedIds)
        {
            try             //涉及多次类型转换与外键关系等操作，应处理异常
            {
                //1.处理前台选中的所有要删除的实体Id信息
                List<int> idList = selectedIds.Split(',').Select(x => int.Parse(x)).ToList();
                //2.执行批量删除操作
                idList.ForEach(x => this.MenuBll.PhysicalDelete(x));
                return OperateContext.Current.JsonModel(1, "删除成功！");
            }
            catch (Exception ex)
            {
                //写入日志

                //返回异常信息
                return OperateContext.Current.JsonModel(0, string.Format("删除失败，{0}", ex.Message));
            }
        }
        #endregion

        #region 08.修改——加载视图
        /// <summary>
        /// 修改菜单节点
        /// </summary>
        /// <param name="id">菜单节点Id</param>
        /// <returns>修改视图</returns>
        public ActionResult Edit(int id)
        {
            MenusView model = this.MenuBll.GetModel(id).ToViewModel();
            //根据栏目Id查询上级栏目的名称，并赋值给ViewBag
            Menus pModel = this.MenuBll.GetModel(model.PId);
            this.ViewBag.PName = pModel == null ? ConfigurationManager.AppSettings["CompanyName"] : pModel.MenuName;
            return this.View(model);
        }
        #endregion

        #region 09.修改——提交修改
        /// <summary>
        /// 提交修改
        /// </summary>
        /// <param name="model">视图模型</param>
        /// <returns>JsonModel</returns>
        public ActionResult EditConfirm(MenusView model)
        {
            //校验模型
            if (this.ModelState.IsValid)
            {
                //1.将用户提交的视图模型转换为数据模型
                Menus dataModel = model.ToDataModel();
                //2.执行修改操作
                if (this.MenuBll.Update(dataModel))
                {
                    return OperateContext.Current.JsonModel(1, "修改成功！");
                }
                else
                {
                    return OperateContext.Current.JsonModel(0, "修改失败，请重试！");
                }
            }
            else    //模型校验失败
            {
                return OperateContext.Current.JsonModel(0, "您输入的数据有误，请重试！");
            }
        }
        #endregion
    }
}
